#include "ComponentAllocator.h"
#include "ComponentHandler.h"
#include "ComponentManager.h"
#include <vector>


template<typename T>
class TComponentAllocator : public ComponentAllocator
{
public:
    TComponentAllocator()
    {
        ComponentManger.getSingleton().add(this);
    }

    virtual ~TComponentAllocator()
    {
        ComponentManger.getSingleton().remove(this);
    }

    T* alloc(Entity* entity)
    {
        components.push_back(T());
        T* ptr = &components[components.size()-1];
        ptr->owner = entity;
        ptr->onstart();
        return ptr;
    }

    void release(T* comp)
    {
        for(auto it = components.begin(); it != components.end();)
        {
            if(it == comp)
            {
                *it = components.back();
	            components.pop_back();
                ptr->onremove();
                break;
            }
            else
                ++it;
        }
    }

    int SortKey() override
    {
        return T::SortKey;
    }

    void frameupdate() override
    {
        for(auto i : components)
        {
            i.frameupdate();
        }
    }
private:
    std::vector<T> components;
};


#define DECLARE_COMPONENT(component) \
    class component##Allocator  \
    : public TComponentAllocator<component>\
    , public Singleton<component##Allocator>\
{\
};\
class component##Handler \
: public ComponentHandler<component,component##Allocator>\
{\
public:\
    component##Handler(Entity* owner)\
        :ComponentHandler<component,component##Allocator>(owner)\
    {\
    }\
};

#define DEFINE_COMPONENT(component,name) component##Handler name